package pl.smath.renderer.model;

import com.google.gwt.user.client.ui.RootPanel;

import gwt.g2d.client.graphics.Surface;
import pl.smath.renderer.renderer.TermRendererException;
import pl.smath.renderer.utils.Cursor;
import pl.smath.renderer.utils.InteractionSocket;
import pl.smath.renderer.utils.Rectangle;

public class FunctionMappingView extends View {

	private View function;
	private View from;
	private View to;
	private final String colonSign = ": ";
	private final String arrowSign = " " + String.valueOf((char)8594) + " ";
	
	/**
	 * C'tors
	 */
	public FunctionMappingView(View function, View from, View to) {
		super("");
		this.function = function;
		this.from = from;
		this.to = to;
	}
	

	/**
	 * render text at the current position
	 * @param canvas
	 */
	@Override
	public void render(Surface canvas, InteractionSocket socket) throws TermRendererException {
		if ((this.getFont() == null)||(this.getFontHeight() == null)) {
			throw new TermRendererException();
		}
		canvas.setFont(this.getFont());
		
		Cursor cursor = this.getCursor();
		
		this.function.render(canvas, socket);
		this.from.render(canvas, socket);
		this.to.render(canvas, socket);
		
		canvas.fillText(colonSign, cursor.getX() + function.getWidth(), cursor.getY());
		
		canvas.fillText(arrowSign, from.getX() + from.getWidth(), cursor.getY());

	}
	
	/**
	 * set the position on canvas to render
	 * @param Cursor
	 */
	@Override
	public void setCursor(Cursor cursor) {
		super.setCursor(new Cursor(cursor.getX(), cursor.getY()));

		Surface surface = new Surface();
		RootPanel.get().add(surface);
		surface.setFont(this.getFont());

		Double dotsWidth = surface.measureText(colonSign);
		Double arrowWidth = surface.measureText(arrowSign);
			
		Cursor toSet = new Cursor(cursor.getX(), cursor.getY());
		
		this.function.setCursor(new Cursor(toSet.getX(), toSet.getY()));
		toSet.setX(toSet.getX() + this.function.getWidth() + dotsWidth);
		this.from.setCursor(new Cursor(toSet.getX(), toSet.getY()));
		toSet.setX(toSet.getX() + this.from.getWidth() + arrowWidth);
		this.to.setCursor(new Cursor(toSet.getX(), toSet.getY()));
		
	}
	
	/**
	 * @param font the font to set
	 */
	@Override
	public void setFont(String font) {
		if (font.indexOf("px")!=-1) {
			this.setFontHeight(new Double(font.substring(0, font.indexOf("px"))));
			this.font = font.substring(font.indexOf("px ")+3);
			this.minusSign.setFont(this.font, this.getFontHeight());

			this.function.setFont(font);
			this.from.setFont(font);
			this.to.setFont(font);
			
			update();
		} else {
			this.setFontHeight(null);
			this.font = null;
		}
	}
	
	/**
	 * updates the view after changes
	 */
	@Override
	public void update() {
		Surface surface = new Surface();
		RootPanel.get().add(surface);
		surface.setFont(this.getFont());

		Double dotsWidth = surface.measureText(colonSign);
		Double arrowWidth = surface.measureText(arrowSign);
		
		this.setRectangle(new Rectangle());
		this.setBaselineOffset(0d);
		
		this.setWidth(this.function.getWidth() + dotsWidth + 
				this.from.getWidth() + arrowWidth + this.to.getWidth());
				
		this.setHeight(Math.max(this.function.getHeight(), Math.max(this.from.getHeight(),this.to.getHeight()) ));

		RootPanel.get().remove(surface);
	}
	
}
